package com.dexin.yang.base.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

@Repository
public class BaseDaoImpl<T extends Serializable, ID extends Serializable>
		extends HibernateDaoSupport implements IBaseDaoService<T, ID> {
	@Autowired
	public void setHibernatetemplate(HibernateTemplate hibernateTemplate) {
		super.setHibernateTemplate(hibernateTemplate);
	}

	@Override
	public List<T> createQuery(final String queryString) {
		HibernateCallback<List<T>> hibernateCallBack = new HibernateCallback<List<T>>() {

			@Override
			public List<T> doInHibernate(Session session)
					throws HibernateException {
				Query query = session.createQuery(queryString);

				List<T> list = query.list();
				return list;
			}
		};
		return getHibernateTemplate().execute(hibernateCallBack);
		// return getHibernateTemplate().find(queryString);
	}

	@Override
	public ID save(final T model) {
		HibernateCallback<ID> hibernateCallBack = new HibernateCallback<ID>() {

			@Override
			public ID doInHibernate(Session session) throws HibernateException {
				return (ID) session.save(model);
			}
		};
		return getHibernateTemplate().execute(hibernateCallBack);
		// return getHibernateTemplate().save(model);
	}

	@Override
	public <T> void update(T model) {
		// TODO Auto-generated method stub
	}

	@Override
	public <T> void delete(T model) {
		// TODO Auto-generated method stub

	}

	@Override
	public T get(final T model) {
		HibernateCallback<T> hibernateCallBack = new HibernateCallback<T>() {

			@Override
			public T doInHibernate(Session session) throws HibernateException {
				Criteria criteria = session.createCriteria(model.getClass());
				List<T> list = criteria.list();
				if (list != null) {
					return list.get(0);
				}
				return null;
			}
		};

		return getHibernateTemplate().execute(hibernateCallBack);

	}
	
	@Override
	public List<T> getAll(final Class<? extends T> clazz) {
		HibernateCallback<List<T>> hibernateCallBack = new HibernateCallback<List<T>>() {

			@Override
			public List<T> doInHibernate(Session session)
					throws HibernateException {
				Criteria criteria = session.createCriteria(clazz);
				List<T> list = (List<T>) criteria.list();
				return list;
			}
		};
		return getHibernateTemplate().execute(hibernateCallBack);
	}

	@Override
	public List<T> getByPage(final String hql, final Object params,
			final Integer start, final Integer size) {
		HibernateCallback<List<T>> callback = new HibernateCallback<List<T>>() {
			public List<T> doInHibernate(Session session) {
				Query query = session.createQuery(hql);
				if (params != null) {
					Class type = params.getClass();
					if (type.isArray()) {
						Object[] tempParams = (Object[]) params;
						int k = 0;
						for (int i = 0; i < tempParams.length; i++) {
							query.setParameter(k++, tempParams[i]);
						}
					} else if (params instanceof Map) {
						query.setProperties((Map) params);
					} else {
						query.setProperties(params);
					}
				}
				if (size > -1) {
					query.setMaxResults(size);
				}
				return query.list();
			}
		};
		List<T> list = getHibernateTemplate().execute(callback);
		return list;
	}

	@Override
	public <T> T get(final Class<? extends T> clazz, final Long id) {
		HibernateCallback callback = new HibernateCallback() {
			public Object doInHibernate(Session session) {
				Object entity = session.get(clazz, id);
				return entity;
			}
		};
		Object obj = getHibernateTemplate().execute(callback);
		return (T) obj;
	}

}
